[CF1234F]Yet Another Substring Reverse

2019-12-19
Codeforces

题意

你可以将字符串的一个子串进行翻转,使得字符串中连续的不出现相同字符的长度最大

$字符集\leq 20$

题解

翻转相当于把两个不相交的子串合并,因为顺序没有影响(如ABC->ACB)

状态压缩,令$f_S$表示答案子串为S的最优解

令T为S的补集,可以发现

预处理Max即可

调试记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn = 1e6 + 5;
using namespace std;
int f[1 << 20], n, ans;
char str[maxn]; bool vis[20];
int main(){
scanf("%s", str + 1); n = strlen(str + 1);
for (int i = 1; i <= n; i++){
int cnt = 0, S = 0;
for (int j = 0; j < 20; j++) vis[j] = 0;
for (int j = i; j <= n; j++)
if (vis[str[j] - 'a']) break;
else{
vis[str[j] - 'a'] = 1;
++cnt;
S |= (1 << (str[j] - 'a'));
f[S] = max(f[S], cnt);
}
}
for (int i = 0; i < (1 << 20); i++)
for (int j = 0; j < 20; j++)
if ((i >> j) & 1) f[i] = max(f[i], f[i ^ (1 << j)]);
for (int i = 0; i < (1 << 20); i++)
ans = max(ans, f[i] + f[((1 << 20) - 1) ^ i]);
printf("%d\n", ans);
return 0;
}